<?php
/**
 * Created by PhpStorm.
 * User: Happy
 * Date: 2016/5/17 0017
 * Time: 17:53
 */
//swoole app control基础控制类
//抽象类,仅仅用于集成,不需要实例化
class Control{
    //tcp 和websocket需要使用
    public $fd;       // client fd
    public $server;   // tcp server object
    public $data;     // client data, array format
    public $client;   // udp client info

    //http 需要使用
    public  $method;

   protected  $request;
   protected  $response;

   protected  $response_write;//是否调用过write
   protected  $response_end;//是否调用过end

    //plugin swoole中初始化request callback会自动赋值
    public function  __construct($request='',$response='')
    {
        $this->request=$request;
        $this->response=$response;
    }
    //获取get参数
    public  function  get($key=''){
        if($key){
            return $this->request->get[$key];
        }
        return $this->request->get;
    }
    //获取post参数
    public  function  post($key=''){
        if($key){
            return $this->request->post[$key];
        }
        return $this->request->post;
    }

    public  function  display($main){
        $this->response_end=true;
        $this->response->end($main);
    }

    protected  function  echos($str){
        $this->response_write=true;
        $this->response->write($str);
    }

     //结束调用
    function  end($str=''){
        if($this->response_write){
            if($str){
                $this->response->write($str);//输出后再end
            }
            $this->response->end();//已经调动write，调用空end就可以
        }
        elseif($this->response_end){
            return '';//已经调用过end 不需要重复调用
        }
        else{
            $this->response_end=true;//已经吊用过就不要重复调用；
            $this->response->end($str);
        }
     }

    //统一service函数接口
    function  send_data($data=array()){
        $this->response->end(json_encode($data));
    }
    //发生错误进行错误输出
    public function error($error, $errorCode = 500){
        if('debug'){//默认都输出
            $rep['Error']  = $error->getMessage();

            $last_error    = log::$last_error;
           $rep['Code']   = $last_error['errorNO'];
            $rep['String'] = $last_error['errorStr'];
           $rep['File']   = $last_error['errorFile'];
           $rep['Line']   = $last_error['errorLine'];
            $rep['Trace']  = $error->getTraceAsString();
        }else{
            $rep['code']  = $errorCode;
            $rep['error'] = 'Internal Server Error';
        }

        if(server::$type == server::TYPE_HTTP){
            $this->httpStatus($errorCode);
            foreach($rep as $key => $val){
                $this->response->write($key. ' => '.$val.'<br />');
            }

            $this->response->end();
        }else{
            foreach($rep as $key => $val){
                $this->response($key. ' => '.$val.PHP_EOL);
            }
        }
    }

    // TCP/UDP/Web Socket 输出数据给客户端
    protected function response($data){
        switch (server::$type) {
            case server::TYPE_TCP:
                return $this->server->send($this->fd, $data);
                break;

            case Server::TYPE_WEB_SOCKET:
                return $this->server->push($this->fd, $data);
                break;

            case Server::TYPE_UDP:
                return $this->server->sendto($this->client['address'], $this->client['port'], $data);
                break;
        }
    }





    //将模板中../resource 全部替换成./resource
    protected  function  replace_resource_path($name){
        $view_path=BASE_PATH.'/views/'.$name.'.html';
        $source=file_get_contents($view_path);
      return  str_replace('../resource','./resource',$source);
    // return preg_replace('~../resource~','./resource',$source);
    }


    //替换和插入layout文件  ,新添加layout设置功能
    protected function  display_layout($main, $layout = 'layout',$layout_setting=array())
    {
        //禁用缓存
        /*
        header('Cache-Control:no-cache,must-revalidate');
        header('Pragma:no-cache');
        header("Expires:0");
        */

        //设置layout_setting中主界面的问题
        $layout_setting['server_name']=c('server_name');
        $layout_setting['meirong_name']=c('meirong_name');
        $layout_setting['meirong_type']=c('meirong_type');
        $layout_setting['meirong_hash']=APP_NAME;
        $layout_setting['stamp']=time();
        $layout_setting['debug']=c('debug');

        $page_main=  $this->fetch_layout($main,$layout,$layout_setting);
        $this->response->end($page_main);
    }

    protected  function  fetch_layout($main, $layout = 'layout',$layout_setting=array()){

        //为了支持多模板需要做处理
        $te_t=c('template');
        if($te_t&&$te_t!='views'){
            $layout_file = BASE_PATH.'/views/template/'.$te_t.'/'.$layout.'.html';
        }
        else{
            $layout_file = BASE_PATH . '/views/'.$layout.'.html';
        }
        if(file_exists($layout_file)){
            $content=file_get_contents($layout_file);
        }
        else{
            throw new Exception('layout file not exits:'.$layout_file);
        }
        $layout_setting['main']=$main;
        $content=BlitzPhp::template($content,$layout_setting);//layout模板赋值
        return $content;
    }
    //显示提示信息  自动退出
    protected  function  show_message($title,$jump_url='index.php',$detail='',$count_down=5,$exit=true){

        if(file_exists(BASE_PATH.'/views/show_message.html')){
               $content=file_get_contents(BASE_PATH.'/views/show_message.html');
        }
        else{  //使用系统默认的跳转样式
             $content=file_get_contents(CORE_PATH.'/tpl/show_message.tpl');
        }
        $main= BlitzPhp::template($content,array(
            'title'=>$title,
            'detail'=>$detail,
            'jmp_url'=>$jump_url,
            'count_down'=>$count_down
        ));
        $this->display_layout($main);
    }
}

//获取一个control,新增支持跨组control,比如mobile使用使用pc的commonContrl
function control($load_control){
    if(strpos($load_control,'/')){//包含区分组件的情况,不包括开始就是/的情况
        $arr=explode('/',$load_control);
        $app=$arr[0];
        $control=$arr[1];
        $file_name = ROOT_PATH .'/'.$app.'/control/' . $control . '.php';
    }
    else{
        $control=$load_control;
        $file_name = BASE_PATH . '/control/' .$control.'.php';
        $load_control=basename(BASE_PATH).'/'.$control;//为了保证键值一致性，添加app前缀。否则可能声明两个对象
    }

    static $_cache = array();
    if (isset($_cache[$load_control])) {
        return $_cache[$load_control];
    }

    if (!$control) //如果为空或null直接返回model对象
    {
        return new Control();
    }

    $class_name = $control . 'Control';

    if (class_exists(@$class_name, false)) { //由于测试是indexControl已经加载过但不是这个方法加载过的，所以没在静态缓存中
        return $_cache[$load_control] = new $class_name();
    }
    include($file_name); //动态引入文件
    if (!class_exists($class_name)) {
        $error = 'Control Error:  Class ' . $class_name . ' is not exists!';
        throw new Exception($error);
    } else {
        return $_cache[$load_control] = new $class_name();
    }
}

//根据，模板快速创建一个control文件,并默认创建index, show——control名称的 函数
function create_control($control){
  $tpl=  file_get_contents(CORE_PATH.'/tpl/createcontrol.tpl');
   $tpl= str_replace('{{control}}',$control,$tpl);
   $target=BASE_PATH.'/control/'.$control.'.php';
    if(file_exists($target)){
        $this->response->end("control $control 文件已经存在，是否要覆盖源文件？");
        throw new Exception("control $control 文件已经存在，是否要覆盖源文件？");
    }
    file_put_contents($target,$tpl);
    $this->response->end('create control '.$control.' success!');
}
//include文件而不实例化
function  include_control($load_control){
    if(strpos($load_control,'/')){//包含区分组件的情况,不包括开始就是/的情况
        $arr=explode('/',$load_control);
        $app=$arr[0];
        $control=$arr[1];
        $file_name = ROOT_PATH .'/'.$app.'/control/' . $control . '.php';
    }
    else{
        $control=$load_control;
        $file_name = BASE_PATH . '/control/' .$control.'.php';
       // $load_control=basename(BASE_PATH).'/'.$control;//为了保证键值一致性，添加app前缀。否则可能声明两个对象
    }
    $class_name = $control . 'Control';
    if (class_exists(@$class_name, false)) { //由于测试是indexControl已经加载过但不是这个方法加载过的，所以没在静态缓存中
     return true;
    }
    else{
        include($file_name); //动态引入文件
    }
}


